Skip to content

Conversation

dreab8
Copy link
Member

@dreab8 dreab8 commented Oct 1, 2025

This is the rebased version of #8678 and shows that the issue has been resolved in recent versions of Hibernate.

https://hibernate.atlassian.net/browse/HHH-18325


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


Some JDBC connection pools create a dynamic reflective Proxy wrapper
around connections in the pool, plus the generated statements and the
result sets those statements create, with the proxies allowing for
methods calls to be intercepted by the connection pool for the purposes
of returning items to the pool when they're released rather than
destroying the underlying database connection. Tomcat's JDBC pool
implementation does not correctly wrap the full chain of objects,
meaning the raw Statement can be retrieved from a ResultSet rather than
returning the proxied statement. This results in the ResourceRegistry
cache attempting to store both the proxied Statement and the non-proxied
Statement in its cache, but encountering an exception when the HashMap
encounters two entries with the same HashCode and then attempts to
differentiate them with an `equals` call which Tomcat's wrapper expects
both instances to be proxied connections. To overcome this issue in
Tomcat, as well as any other pool implementation which may use Proxy
classes but leak the un-proxied entries, the original PreparedStatement
used to create the ResultSet is being passed into the
GeneratedValuesHelper for passing into the ResourceRegistry, rather than
the GeneratedValues helper attempting to extract the Statement from the
ResultSet.
private static final SingleConnectionDataSource SINGLE_CONNECTION_DATASOURCE = new SingleConnectionDataSource();

@AfterAll
public void tearDown(SessionFactoryScope scope) {

Check notice

Code scanning / CodeQL

Useless parameter Note test

The parameter 'scope' is never used.
connectionProvider.configure(
PropertiesHelper.map( ConnectionProviderBuilder.getConnectionProviderProperties() ) );
try {
connectionQueue.add( new ConnectionWrapper( connectionProvider.getConnection(), this ) );

Check warning

Code scanning / CodeQL

Potential database resource leak Warning test

This ConnectionWrapper is not always closed on method exit.
@dreab8 dreab8 merged commit 21b62db into hibernate:main Oct 1, 2025
21 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants